文档:https://www.mongodb.org.cn/tutorial/9.html
https://docs.mongodb.com/manual/
菜鸟文档:https://www.runoob.com/mongodb/mongodb-tutorial.html
toc and abstract of fore4days.
<!–
# 8天学通MongoDB
简单入门;简要抄了前四天。后四天高级过了一下,理解没有不知道。反正没有实践过
这几天(2018年3月)掌握了一些简单API的高级操作,主要是操作符的使用;还是和php 搭配
从文章链接可以大概看到发表时间
–>
2017.9.22 星期五 17:24
Ⅰ 基础入门
1 下载
目录结构:mongodb /bin/*.exe GNU-AGPL–3.0 README THIRD-PARTY-NOTICES
2 启动 mongod –path=E:mongodb/db
先建立数据存放文件夹 mongodb/db
3 基本操作
insert
db.person.insert({"name":"jack","age":20})
find
db.person.find()
update
db.person.update({"name":"jack"},{"name":"joe","age":30})
remove (count)
db.person.remove() db.person.find() db.person.count()
Ⅱ 细说增删查改
插曲:打不开mongodbl–》干掉“lock file”文件(管理方式中分享)
一 insert操作
JSON BSON
单条插入
mongo命令打开的是js shell,所以js语法同。var single={.. } db.person.insert(single)
- 批量插入
没有提供给shell 这样的方法,可以自己写for循环,里面insert二 find操作
$gt $gte $lt $lte $ne 无 ===== >,>=,<,<=,!=,=
db.mycol.find({"likes":{$lt:50}})
- 无 $or $in $nin ========and,or,in,notin
- 正则
$where
db.user.find({$where:function(){return this.name=='jack'}})
三 update操作
- 整体更新
update (上一篇的) 局部更新
$inc increase,没有就创建
db.user.update({"name":"jack},{$inc:{"age":30}})
$set
db.user.update({"name":"jack},{$set:{"age":30}})
upsert操作
没查到就新增一条,避免 update,add判断。。第三个参数设truedb.user.update({"name":"jack},{$inc:{"age":30}},true)
- 批量更新
第四个参数设为true
四 remove操作
上一篇讲了
Ⅲ 细说高级操作
主要包括:聚合,游标
一 聚合
count distinct group mapReduce
count
db.person.count() db.person.count({"age":20})
distinct
db.person.distinct("age")
group
三个参数
过滤:两个可选参数:conditon finalizedb.person.group({ "key":{"age":true},//分组的key "initial":{"person":[]},//每组都分享一个“初始函数”:20一个,22一个 "$reduce":function(cur,prev){ //cur当前文档对象, //prev上一次function操作的累计对象,第一次为{"person":[]}。有多少文档,就调用继承 prev.person.push(cur.name) }, "finalize":function(){ out.count=out.person.length; }, "condition":{"age":{$lt:25}} }) //输出 [ { "age":20, "person":["jack","mary"], "count":2 //可选参数 }, { "age":22, "person":["jack2","mary2","fugui"], "count":3 //可选参数 }, //过滤后下面的就没有了 { "age":26, "person":["jack11","mary"] } ]
mapReduce
这玩意算是聚合函数中最复杂的了,不过复杂也好,越复杂就越灵活。mapReduce其实是一种编程模型,用在分布式计算中,其中有一个“map”函数,一个”reduce“函数。
map:
这个称为映射函数,里面会调用emit(key,value),集合会按照你指定的key进行映射分组。reduce:
这个称为简化函数,会对map分组后的数据进行分组简化,注意:在reduce(key,value)中的key就是emit中的key,vlaue为emit分组后的emit(value)的集合,这里也就是很多{“count”:1}的数组。
mapReduce:
这个就是最后执行的函数了,参数为map,reduce和一些可选参数。具体看图可知:function map(){ emit(this.name,{count:1}); } function reduce(key,value){ var result={count:0}; for(var i=0;i<value.length;i++){ result.count+=value[i].count; } return result; } db.person.mapReduce(map,reduce,{"out":"collection"}) { "result":"collection",//存放的集合名 "timeMillis":14,// "counts":{ "input":7,//传入文档的个数 "emit":,7,//此函数被调用的次数 "reduce":3,//此函数被调用的次数 "output":4//最后返回文档的个数 }, "ok":1, } //最后我们看一下“collecton”集合里面按姓名分组的情况。 db.collection.find()
二 游标
针对这样的操作,list其实并没有获取到person中的文档,
而是申明一个“查询结构”,
等我们需要的时候通过for或者next()一次性加载过来,然后让游标逐行读取,
当我们枚举完了之后,游标销毁,(之后我们在通过list获取时,发现没有数据返回了)
var list=db.person.find();
list.forEach(function(x){
print(x.name)
})
//逐个输出后
list
//没有数据返回了
当然我们的“查询构造”还可以搞的复杂点,比如分页,排序都可以加进去。
那么这样的“查询构造”可以在我们需要执行的时候执行,大大提高了不必要的花销。
var single=db.person.find().sort({"name",1}).skip(2).limit(2);
Ⅳ 索引操作
CURD,通常我们又会花费50%的时间在R上面
5种经典的查找,包括我们今天所说的“索引查找”
我们首先插入10w数据
一 性能分析函数 explain
仔细看红色区域,有几个我们关心的key:
cursor: 这里出现的是”BasicCursor”,什么意思呢,就是说这里的查找采用的是“表扫描”,也就是顺序查找,很悲催啊。
nscanned: 这里是10w,也就是说数据库浏览了10w个文档,很恐怖吧,这样玩的话让人受不了啊。
n: 这里是1,也就是最终返回了1个文档。
millis: 这个就是我们最最最….关心的东西,总共耗时114毫秒。
db.person.find({"name":"hxc"+1000}).explain()
二 建立索引 ensureIndex
db.person.ensureIndex({"name":1}) //-1降序
db.person.find({"name":"hxc"+1000}).explain()
三 唯一索引
db.person.ensureIndex({"name":1},{"unique":true})
db.person.insert({"name":"hxc","age":20})
db.person.insert({"name":"hxc","age":22})//报错
四 组合索引
有时候我们的查询不是单条件的,可能是多条件
db.person.ensureIndex({"name":1,"birthday":1}) db.person.ensureIndex({"birthday":1,"name":1})
看到上图,大家或者也知道name跟birthday的不同,建立的索引也不同,升序和降序的顺序不同都会产生不同的索引,
那么我们可以用getindexes来查看下person集合中到底生成了那些索引。
db.person.getIndexes()
此时我们肯定很好奇,到底查询优化器会使用哪个查询作为操作,呵呵,还是看看效果图:
db.person.find({"birthday":"1989-3-2","name":"jack"}).explain()
看完上图我们要相信查询优化器,它给我们做出的选择往往是最优的,因为我们做查询时,查询优化器会使用我们建立的这些索引来创建查询方案,
如果某一个先执行完则其他查询方案被close掉,这种方案会被mongodb保存起来,
当然如果非要用自己指定的查询方案,这也是可以的,在mongodb中给我们提供了hint方法让我们可以暴力执行。
db.person.find({"birthday":"1989-3-2","name":"jack"}).hint({"birthday":"1989-3-2","name":"jack"}).explain()
五 删除索引
可能随着业务需求的变化,原先建立的索引可能没有存在的必要了,
(可能有的人想说没必要就没必要呗,)
但是请记住,索引会降低CUD这三种操作的性能,因为这玩意需要实时维护,所以啥问题都要综合考虑一下,这里就把刚才建立的索引清空掉来演示一下:dropIndexes的使用。
db.person.dropIndexes("name_1")
长_天_B#805 2017.9.22五 19:24
章节 | 学习情况 | 截止日期 | 后期安排 |
---|---|---|---|
noted | 前四天noted | 2017.9.22 | deSituation |
coded | 后四天coded | 2017.9.22 | deSituation |
八天全 | 之前过了一遍 | 2017.9.* | ———- |
前四天 | 看了半块 | 2017.9.22 5 | waitToWork |
后四天 | ——— | ——— | dework |